/**
 * 接口 行为的抽象 对象的形状
 */

 // 1 对象的形状
 namespace aa {
  interface Speakable {
    speak():void;
    name:string;
  }
  let person:Speakable = {
    name: 'circe',
    speak(){}
  }
 }

// 2 行为的抽象
namespace b {
  interface Speakable {
    speak():void
  }
  interface Eatable {
    eat():void
  }
  class Person implements Speakable,Eatable {
    speak(): void {
      throw new Error("Method not implemented.");
    }    
    eat(): void {
      throw new Error("Method not implemented.");
    }

  }
}
namespace c{
  //任意属性
  // interface Person {
  //   name: string,
  //   age: number,
  //   [key:string]: any
  // }
  // 或者使用继承：
  interface Person extends Record<string,any>{
    name: string,
    age: number,
    readonly PI: number
  }
  
  let p:Person = {
    name: 'ggu',
    age:18,
    home: 'hangzhou',
    PI: 3.14
  }
  // p.PI = 3.15 只读属性不能修改
}

//函数接口类型
namespace d {
  // type和interface区别：type只是定义一个类型别名，interface才是真正的类型
  // type Cost  = (price:number) => number;
  interface Cost {
    (price:number): number
   }

  let cost:Cost = function(price){
    return price * 8;
  }
  
  interface Person {
    cost: (price:number)=> number //注意修饰对象时不能用冒号
  }
  let p:Person = {
    cost
  }
}

//可索引接口 对数组和对象进行约束
namespace e {
   interface UserInterface {
     [index:number]: string
   }
   let arr:UserInterface = ['1','2'];
   let obj:UserInterface = {0: '1',1:'b'};
}

namespace f {
  //类接口 类的类型
  interface Speakable {
    name: string,
    speak(words:string):void
  }
  class Dog implements Speakable{
    name: string;    
    speak(words: string): void {
      console.log(words)
    }
  }
  let dog = new Dog();
  dog.speak('wangwang');
}
namespace h {
  class Animal {
    constructor(public name:string){

    }
  }
  interface withNameClazz {
    new(name:string): Animal //约束构造函数
  }
  function create(clazz:withNameClazz,name:string){
    return new clazz(name)
  }
  let a = create(Animal,'dog'); 
}